package background.orgin;

/**
 * 描述：     观察者模式
 * 我得到的数字是 有可能是0
 * 本意是想让它初始化为100,
 */
public class MultiThreadsError5 {

    int count;

    public MultiThreadsError5(MySource source) {
        source.registerListener(new EventListener() {
            @Override
            public void onEvent(Event e) {
                System.out.println("\n我得到的数字是" + count); //拥有外面count的引用,这是问题所在
            }

        });

        for (int i = 0; i < 1000; i++) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (i % 100 == 0) {
                System.out.print("--"+i);
            }

        }
        // 当主线程中,初始化时间过久(上面就模拟了耗时较久的过程),在子线程中直接访问count的引用,本意是在此方法中初始化count为100
        //但是主线程慢,子线程快,就导致子线程访问得到了count=0.
        count = 100;
    }

    public static void main(String[] args) {
        MySource mySource = new MySource();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
//                    Thread.sleep(4000); // 得到count=100
                    Thread.sleep(10); //得到count=0
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mySource.eventCome(new Event() {
                });
            }
        }).start();
        MultiThreadsError5 multiThreadsError5 = new MultiThreadsError5(mySource);
    }

    static class MySource {

        private EventListener listener;

        //main线程调用
        void registerListener(EventListener eventListener) {
            this.listener = eventListener;
        }

        // 子线程调用
        void eventCome(Event e) {
            if (listener != null) {
                listener.onEvent(e);
            } else {
                System.out.println("还未初始化完毕呢....");
            }
        }

    }

    interface EventListener {

        void onEvent(Event e);
    }

    interface Event {

    }
}
